﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Spring.Context;
using Common.Logging;
using Spring.Context.Support;
using System.Collections;
using Spring.Data.NHibernate.Generic;
using Spring.Data.Generic;
using NHibernate.Id;

namespace Domain.Repository
{
    public class SpringObjectUtil : IApplicationContextAware
    {
        private ILog logger = LogManager.GetLogger(typeof(SpringObjectUtil));
        private IApplicationContext applicationContext;

        private static SpringObjectUtil _instance;

        public static SpringObjectUtil Instance
        {
            get { return SpringObjectUtil._instance; }
        }

        public SpringObjectUtil()
        {
            SpringObjectUtil._instance = this;
        }

        public IApplicationContext ApplicationContext
        {
            set
            {
                this.applicationContext = value;
                logger.Info("=====>>Created application context has been successful use the CodeConfig : " + this.applicationContext);
                logger.Info("=====>>Objects definition count are : " + this.applicationContext.ObjectDefinitionCount);
                string[] objNames = SpringObjectUtil.Instance.GetObjectDefinitionNames();
                foreach (string entry in objNames)
                {
                    logger.Info("=====>>Object name : " + entry);
                }
            }
        }

        public StatementManagement StatementManagement
        {
            get
            {
                return this.applicationContext.GetObject<StatementManagement>("StatementManagement");//StatementManagement
            }
        }

        public string GetSqlStatement(string sqlkey)
        {
            return this.StatementManagement.SqlStatements[sqlkey];
        }

        /// <summary>
        /// Main HibernateTemplate
        /// </summary>
        public HibernateTemplate HibernateTemplate
        {
            get
            {
                return this.applicationContext.GetObject<HibernateTemplate>("mainHibernateTemplate");
            }
        }

        /// <summary>
        /// mainQueryTemplate, use the query cache service
        /// </summary>
        public IQueryTemplate QueryTemplate
        {
            get
            {
                return this.applicationContext.GetObject<IQueryTemplate>("mainQueryTemplate");
            }
        }


        /// <summary>
        /// noCacheQueryTemplate, no use the query cache service
        /// </summary>
        public IQueryTemplate NoCacheQueryTemplate
        {
            get
            {
                return this.applicationContext.GetObject<IQueryTemplate>("noCacheQueryTemplate");
            }
        }

        public string GenerateGuidComb()
        {
            GuidCombGenerator generator = new GuidCombGenerator();
            return generator.Generate(null, null).ToString().Replace("-", String.Empty);
        }

        #region Method wrapper for IApplicationContext
        public object GetObject(string name)
        {
            return this.applicationContext.GetObject(name);
        }

        public object GetObject(string name, object[] arguments)
        {
            return this.applicationContext.GetObject(name, arguments);
        }

        public object GetObject(string name, Type requiredType)
        {
            return this.applicationContext.GetObject(name, requiredType);
        }

        public object GetObject(string name, Type requiredType, object[] arguments)
        {
            return this.applicationContext.GetObject(name, requiredType, arguments);
        }

        public T GetObject<T>() where T : class
        {
            return this.applicationContext.GetObject<T>();
        }



        public T GetObject<T>(string name) where T : class
        {
            return this.applicationContext.GetObject<T>(name);
        }

        public Type GetType(string name)
        {
            return this.applicationContext.GetType(name);
        }


        public bool IsPrototype(string name)
        {
            return this.applicationContext.IsPrototype(name);
        }

        public bool IsSingleton(string name)
        {
            return this.applicationContext.IsSingleton(name);
        }

        public bool IsTypeMatch(string name, Type targetType)
        {
            return this.applicationContext.IsTypeMatch(name, targetType);
        }


        public bool ContainsLocalObject(string name)
        {
            return this.applicationContext.ContainsLocalObject(name);
        }


        public bool ContainsObject(string name)
        {
            return this.applicationContext.ContainsObject(name);
        }

        public int ObjectDefinitionCount
        {
            get
            {
                return this.applicationContext.ObjectDefinitionCount;
            }
        }

        public bool ContainsObjectDefinition(string name)
        {
            return this.applicationContext.ContainsObjectDefinition(name);
        }

        public string[] GetObjectDefinitionNames()
        {
            return this.applicationContext.GetObjectDefinitionNames();
        }

        public string[] GetObjectNamesForType(Type type)
        {
            return this.applicationContext.GetObjectNamesForType(type);
        }

        public string[] GetObjectNamesForType(Type type, bool includePrototypes, bool includeFactoryObjects)
        {
            return GetObjectNamesForType(type, includePrototypes, includeFactoryObjects);
        }

        public IDictionary GetObjectsOfType(Type type)
        {
            return this.applicationContext.GetObjectsOfType(type);
        }

        public IDictionary GetObjectsOfType(Type type, bool includePrototypes, bool includeFactoryObjects)
        {
            return this.applicationContext.GetObjectsOfType(type, includePrototypes, includeFactoryObjects);
        }
        #endregion
    }
}
